﻿using System.Linq;
using System.Linq.Expressions;
using CoreEx.Database.Linq.Translators;
using CoreEx.Database.Query.Expressions;
using LinFu.IoC.Configuration;

namespace CoreEx.Database.Linq.Implementation.Translators
{
    /// <summary>
    /// Handles calls to the <see cref="Queryable.Where{TSource}(System.Linq.IQueryable{TSource},System.Linq.Expressions.Expression{System.Func{TSource,bool}})"/> method 
    /// and and translates it into a <see cref="DbQuery{TQueryExpression}"/> instance.
    /// </summary>
    [Implements(typeof(IExpressionTranslator_generic<MethodCallExpression>), ServiceName = "Where")]
    public class WhereMethodCallExpressionTranslator : MethodCallExpressionTranslatorGeneric
    {

        /// <summary>
        /// Initializes a new instance of the <see cref="WhereMethodCallExpressionTranslator"/> class.
        /// </summary>
        /// <param name="translateResult">The <see cref="TranslateResult"/> that
        /// provides aggregated information about the current query translation process.</param>
        public WhereMethodCallExpressionTranslator(TranslateResult translateResult)
            : base(translateResult) { }

        /// <summary>
        /// Translates the <paramref name="expression"/> into a <see cref="DbQuery{TQueryExpression}"/> instance.
        /// </summary>
        /// <param name="expression">The <see cref="MethodCallExpression"/> to translate.</param>
        /// <returns><see cref="DbQuery{TQueryExpression}"/></returns>
        public override DbExpression Translate(MethodCallExpression expression)
        {                        
            var dbSelectQuery = (DbQuery<DbSelectExpression>)Visit(expression.Arguments[0]);
            var lambdaExpression = expression.Arguments[1].StripQuotes();
            var whereClause = Visit(lambdaExpression);
            return dbSelectQuery.Where(whereClause);
        }
    }
}
